<template>
  <div class="min-h-200 flex-col items-center gap-y-20">
    <MyToggle v-model="active" :options="tabs" />
    <div v-show="active === 'first'" style="width: 100%">
      <n-spin :show="loading">
        <n-collapse v-model:expanded-names="data.names" display-directive="show">
          <template #arrow>
            <div></div>
          </template>
          <n-collapse-item v-for="item in data.list" :key="item.key" :name="item.key">
            <template #header>
              <img :src="item.icon" />
              <div class="ml-10 font-size-16 color-#030912 font-bold">{{ item.text }}</div>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon
                    :component="ArrowRightRound"
                    :size="26"
                    :color="data.names.includes(item.key) ? '#0a56d8' : ''"
                  ></n-icon>
                </template>
                {{ data.names.includes(item.key) ? '收起' : '展开' }}
              </n-tooltip>
            </template>
            <template v-if="item.type === 1">
              <n-form
                :ref="(el) => (item.$form = el)"
                :model="item.model"
                label-placement="left"
                require-mark-placement="left"
              >
                <n-flex justify="space-between">
                  <n-form-item label="项目体量" path="bodyCode">
                    <n-radio-group
                      v-model:value="item.model.bodyCode"
                      :disabled="!hasPermission('test_first_handle')"
                      @update:value="item.model.standard = null"
                    >
                      <n-radio value="LITTLE">小</n-radio>
                      <n-radio value="BIG">大</n-radio>
                    </n-radio-group>
                  </n-form-item>
                  <n-button
                    color="#0A56D8FF"
                    size="small"
                    :loading="item.loading"
                    :disabled="!hasPermission('test_first_handle')"
                    @click="item.handleSave"
                  >
                    保存
                  </n-button>
                </n-flex>
                <n-form-item
                  label="本项目标准"
                  path="standard"
                  :rule="[{ required: true, message: '请选择项目标准！' }]"
                >
                  <AsyncSelect
                    v-model:value="item.model.standard"
                    style="width: 600px"
                    :options="item.model.bodyCode"
                    :disabled="!hasPermission('test_first_handle')"
                  />
                </n-form-item>
                <n-form-item
                  path="problemList"
                  :rule="[{ type: 'array', validator: validatorPerson }]"
                >
                  <Problem
                    v-model="item.model.problemList"
                    :project-id="props.detail.id"
                    :header="item.header"
                    :disabled="!hasPermission('test_first_handle')"
                  />
                </n-form-item>
              </n-form>
            </template>
            <template v-if="item.type === 2">
              <n-flex justify="flex-end">
                <n-button
                  color="#0A56D8FF"
                  size="small"
                  :loading="item.loading"
                  :disabled="!hasPermission('test_first_handle')"
                  @click="item.handleSave"
                >
                  保存
                </n-button>
              </n-flex>
              <n-form
                :ref="(el) => (item.$form = el)"
                :model="item.model"
                label-placement="left"
                require-mark-placement="left"
                label-align="right"
                :label-width="140"
              >
                <n-form-item
                  label="测试人员"
                  path="testPersonnel"
                  :rule="[{ required: true, type: 'array', min: 1, message: '请选择测试人员' }]"
                >
                  <AsyncSelect
                    v-model:value="item.model.testPersonnel"
                    :options="getUserOptions"
                    label-key="name"
                    value-key="userId"
                    :remote="true"
                    :init-remote="true"
                    :multiple="true"
                    style="width: 400px"
                    :disabled="!hasPermission('test_first_handle')"
                  />
                </n-form-item>
                <n-form-item
                  label="测试时间"
                  path="timeRange"
                  :rule="[{ required: true, message: '请填入测试时间' }]"
                >
                  <n-date-picker
                    v-model:formatted-value="item.model.timeRange"
                    type="datetimerange"
                    value-format="yyyy-MM-dd HH:mm:ss"
                    format="yyyy-MM-dd HH:mm"
                    :time-picker-props="{ format: 'HH:mm' }"
                    :default-time="['09:00:00', '18:30:00']"
                    clearable
                    :disabled="!hasPermission('test_first_handle')"
                  />
                </n-form-item>
                <n-form-item label="测试bug记录清单" path="testBugRecord">
                  <n-input
                    v-model:value="item.model.testBugRecord"
                    clearable
                    :maxlength="100"
                    style="width: 600px"
                    :disabled="!hasPermission('test_first_handle')"
                  />
                </n-form-item>
              </n-form>
            </template>
          </n-collapse-item>
        </n-collapse>
      </n-spin>
    </div>
    <Record
      v-if="active === 'doc'"
      :id="detail.id"
      :apis="testRecordApis"
      :permission-keys="{
        list: 'test_doc_list',
        add: 'test_doc_add',
        edit: 'test_doc_update',
        del: 'test_doc_delete',
      }"
    />
  </div>
</template>
<script setup lang="jsx">
import { usePermissionStore } from '@/store'
import { useAuthTabs } from '@/hooks/useAuthTabs'
import { ArrowRightRound } from '@vicons/material'
import * as projectApi from '@/api/project'
import { userSel } from '@/api/user'
import { formatToIds, formatToSel } from '@/utils/format'
import test01 from '@/assets/icons/test-01.png'
import test02 from '@/assets/icons/test-02.png'
import test03 from '@/assets/icons/test-03.png'
import test04 from '@/assets/icons/test-04.png'
defineOptions({ name: 'TestManage' })
const props = defineProps({
  detail: {
    type: Object,
    default: () => ({}),
  },
})
const testRecordApis = {
  add: projectApi.testRecordAdd,
  list: projectApi.testRecordList,
}
const { hasPermission } = usePermissionStore()

function validatorPerson(_, value, callback) {
  if (Array.isArray(value)) {
    if (value.some((item) => !item.userId)) {
      callback(new Error('人员不能为空'))
    }
    const trueLength = [...new Set(value.map((item) => item.userId).filter((userId) => userId))]
      .length
    if (trueLength !== value.length) {
      callback(new Error('存在重复人员'))
    } else {
      callback()
    }
  } else {
    callback()
  }
}
//type 1/2
const useSave = (type, categoryType) => {
  const header = ref({})
  const $form = ref(null)
  const loading = ref(false)
  const model = reactive(
    type === 1
      ? {
          standard: null,
          problemList: [],
          bodyCode: 'LITTLE',
        }
      : {
          testPersonnel: null,
          testBugRecord: null,
          timeRange: null,
        }
  )
  function handleSave(e) {
    e.preventDefault()
    $form.value.validate(async (errors) => {
      if (!errors) {
        loading.value = true
        const [testTimeStart, testTimeEnd] = model?.timeRange || []
        const task =
          type === 1
            ? projectApi.testSave(model.standard, {
                standardsPeopleDtoList: model.problemList,
                projectId: props.detail.id,
                categoryType,
                bodyCode: model.bodyCode,
              })
            : projectApi.testProcessSave({
                projectId: props.detail.id,
                testPersonnel: formatToIds(model.testPersonnel),
                testBugRecord: model.testBugRecord,
                testTimeStart,
                testTimeEnd,
              })

        task
          .then(async () => {
            await getDetail()
            $message.success('保存成功！')
          })
          .finally(() => {
            loading.value = false
          })
      }
    })
  }
  return {
    $form,
    loading,
    header,
    model,
    handleSave,
  }
}
const {
  $form: $form1,
  header: header1,
  model: model1,
  loading: loading1,
  handleSave: handleSave1,
} = useSave(1, 'frontRestoration')

const {
  $form: $form2,
  header: header2,
  model: model2,
  loading: loading2,
  handleSave: handleSave2,
} = useSave(1, 'frontDocking')

const {
  $form: $form3,
  header: header3,
  model: model3,
  loading: loading3,
  handleSave: handleSave3,
} = useSave(1, 'backendRate')

const { $form: $form4, model: model4, loading: loading4, handleSave: handleSave4 } = useSave(2)
function getUserOptions(name, userIds) {
  return userSel({ name, userIds: formatToIds(userIds) }).then((res) => res.data)
}
const { tabs, active } = useAuthTabs([
  { label: '首轮测试', value: 'first', key: 'test_first' },
  { label: '测试过程文档', value: 'doc', key: 'test_doc' },
])
const data = reactive({
  names: [],
  list: [
    {
      key: 'frontRestoration',
      text: '前端还原度',
      icon: test01,
      type: 1,
      $form: $form1,
      header: header1,
      model: model1,
      loading: loading1,
      handleSave: handleSave1,
    },
    {
      key: 'frontDocking',
      text: '前端对接',
      icon: test02,
      type: 1,
      $form: $form2,
      header: header2,
      model: model2,
      loading: loading2,
      handleSave: handleSave2,
    },
    {
      key: 'backendRate',
      text: '后端完成度',
      icon: test03,
      type: 1,
      $form: $form3,
      header: header3,
      model: model3,
      loading: loading3,
      handleSave: handleSave3,
    },
    {
      key: 'testProcess',
      text: '测试过程',
      icon: test04,
      type: 2,
      $form: $form4,
      model: model4,
      loading: loading4,
      handleSave: handleSave4,
    },
  ],
})
const loading = ref(false)
async function getDetail() {
  try {
    loading.value = true
    const [res1, res2] = await Promise.all([
      projectApi.testList({ projectId: props.detail.id }),
      projectApi.testProcessInfo(props.detail.id),
    ])
    const {
      standardsPeopleVoMap: {
        frontRestoration: [standard1, ...data1],
        frontDocking: [standard2, ...data2],
        backendRate: [standard3, ...data3],
      },
      frontDockingStandard,
      frontDockingBody = 'LITTLE',
      frontRestorationStandard,
      frontRestorationBody = 'LITTLE',
      backendRateStandard,
      backendRateBody = 'LITTLE',
    } = res1.data
    const { testPersonnel, testTimeStart, testTimeEnd, testBugRecord } = res2?.data || {}
    header1.value = standard1
    model1.problemList = data1
    model1.standard = frontRestorationStandard
    model1.bodyCode = frontRestorationBody
    header2.value = standard2
    model2.problemList = data2
    model2.standard = frontDockingStandard
    model2.bodyCode = frontDockingBody
    header3.value = standard3
    model3.problemList = data3
    model3.standard = backendRateStandard
    model3.bodyCode = backendRateBody
    model4.testPersonnel = formatToSel(testPersonnel)
    model4.testBugRecord = testBugRecord
    model4.timeRange = testTimeStart && testTimeEnd ? [testTimeStart, testTimeEnd] : null
    loading.value = false
  } catch (error) {
    loading.value = false
  }
}
watch(
  () => props.detail.id,
  (val) => {
    if (val) {
      nextTick(() => {
        getDetail()
      })
    }
  },
  {
    immediate: true,
  }
)
</script>
<style lang="scss" scoped></style>
